<template>
  <div class="match-tab-container">
    <div v-if="matchDetail.ID">
      <div class="home-h5-header">
        <span class="home-h5-title">{{ matchDetail?.name || "比赛名称" }}</span>
      </div>
      <div class="home-h5-status-row">
        <el-tag
          class="container-header-activityTag"
          :type="jianchatime(matchDetail, datenow).type"
          effect="dark"
          size="default"
        >
          {{ jianchatime(matchDetail, datenow).text2 }}
        </el-tag>
        <el-tag class="container-header-activityTime" v-if="!isActivityEnd">
          距{{ n }}: <span>{{ time.d }}</span
          >天 <span>{{ time.h }}</span
          >时 <span>{{ time.m }}</span
          >分 <span>{{ time.s }}</span
          >秒
        </el-tag>
      </div>
      <div class="home-h5-card">
        <div class="home-h5-row">
          <span>比赛类型：</span>
          <span class="home-h5-question-count">
            {{ matchDetail.type === "public" ? "公开" : "非公开" }}
          </span>
        </div>
        <div class="home-h5-row">
          <span>计时方式：</span>
          <span class="home-h5-question-count">
            {{ matchDetail.duration ? "个人计时" : "统一计时" }}
          </span>
        </div>
        <div v-if="user">
          <div class="home-h5-row">
            <span>题目数：</span>
            <span class="home-h5-question-count">
              <template
                v-if="Object.keys(matchQuestionComputed.info || {}).length"
              >
                <span v-for="(v, k) in matchQuestionComputed.info" :key="k">
                  {{ `${k}题：${v.count}` }}&nbsp;&nbsp;
                </span>
              </template>
              <template v-else>
                {{ "题目：0" }}
              </template>
            </span>
          </div>
          <div class="home-h5-row">
            <span>总分：</span>
            <span class="home-h5-question-count">
              {{
                matchQuestionComputed.totalScore ||
                matchDetail?.totalscore ||
                "0"
              }}
              分
            </span>
          </div>
        </div>
        <div class="home-h5-row">
          <span>答题时长：</span>
          <span class="home-h5-question-count">
            {{
              matchDetail.duration
                ? `${(matchDetail.duration / 60).toFixed(1)}小时`
                : timeDiff(
                    matchDetail.activitystarttime,
                    matchDetail.activityendtime
                  )
            }}
          </span>
        </div>
        <div class="match-status-container">
          <el-button
            v-if="isActivityEnd"
            class="match-end-btn"
            round
            type="info"
            plain
            disabled
          >
            <el-icon class="btn-icon">
              <Clock />
            </el-icon>
            &nbsp; 比赛已结束
          </el-button>
          <el-button
            v-else
            class="home-h5-btn blue"
            type="primary"
            round
            @click="goToMatch"
          >
            <el-icon class="btn-icon">
              <Opportunity />
            </el-icon>
            &nbsp;{{ hasAnswered ? "查看答题" : "开始答题" }}
          </el-button>
        </div>
        <div
          class="home-h5-row contact-info-row"
          v-if="matchDetail?.customerserviceid"
        >
          <span>如有问题请联系老师：</span>
          <span class="home-h5-question-count contact-qr-code">
            <img
              :src="matchDetail?.customerservice?.qrcode"
              width="120"
              alt="联系老师二维码"
            />
          </span>
        </div>
      </div>
      <div class="home-h5-card home-h5-desc">
        <div class="home-h5-row home-h5-desc-title">比赛说明：</div>
        <div class="home-h5-row home-h5-desc-content">
          <span v-html="matchDetail?.context"></span>
        </div>
      </div>
      <!-- 邀请码弹窗 -->
      <el-dialog v-model="invitationDialog" title="邀请码" width="96%">
        <template #header>
          <span class="icon-text el-dialog__header-title">
            <el-icon class="text-primary">
              <Guide />
            </el-icon>
            邀请码
          </span>
        </template>
        <div class="invitation-form">
          <div
            class="home-h5-row contact-info-row in-dialog-contact"
            v-if="matchDetail?.info?.customerservice"
          >
            <span>如有问题请联系老师：</span>
            <span class="home-h5-question-count contact-qr-code">
              <img
                :src="matchDetail?.info?.customerservice"
                width="120"
                alt="联系老师二维码"
              />
            </span>
          </div>
          <el-input
            size="large"
            v-model="invitationvalue"
            placeholder="进入该比赛需要邀请码，如无邀请码，请联系老师"
            clearable
          >
          </el-input>
          <el-button size="large" type="primary" @click="invitationSubmit">
            确定
          </el-button>
        </div>
      </el-dialog>
    </div>
    <div v-else class="home-h5-card home-h5-desc no-match-info-tips">
      <div class="home-h5-row home-h5-desc-title">
        <h4>暂无比赛项目</h4>
      </div>
      <div class="home-h5-row home-h5-desc-content">
        请联系管理员确认比赛地址
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { Clock, Guide, Opportunity } from "@element-plus/icons-vue";
import { dayjs, ElMessage } from "element-plus";
import { computed, onMounted, onUnmounted, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
import {
  asyncchangeactivityuser,
  asyncgetactivity,
  asyncgetactivityuser,
  asyncselectmatchuserquestion,
} from "../../api";
import { Storekey } from "../../interface";
import Studycodemodel from "../../mysql_interface/studycodemodel";
import { dhms, jianchatime } from "@/util/jianchatime";

const enum Tabs {
  MATCH = "match",
  USER = "user",
}

const route = useRoute();
const router = useRouter();
const store = useStore(Storekey);
const defaultMatchId = 0;

const tab = ref<Tabs>(Tabs.MATCH);
const showEdit = ref(false);
const user = computed<Studycodemodel.Iuser | undefined>(() => store.state.user);
const activityId = computed(
  () => Number(route.query.activityId) || defaultMatchId
);

const matchDetail = ref<any>({});
const datenow = computed(() => store.state.time!);
const time = reactive({ d: 0, h: 0, m: 0, s: 0 });
const n = ref("结束");
const timer = ref<number>();
const isActivityEnd = computed(() => {
  if (matchDetail.value?.activityendtime) {
    return (
      new Date(matchDetail.value.activityendtime).getTime() < datenow.value
    );
  }
  return false;
});
const matchQuestion = ref<any[]>([]);
const matchQuestionComputed = computed(() => {
  const info: Record<string, { count: number; score: number }> = {};
  let totalScore = 0;
  (matchQuestion.value || []).forEach((e: any) => {
    const { type, score } = e;
    if (!type) return;
    if (info[type]) {
      info[type].count++;
      info[type].score += score || 0;
    } else {
      info[type] = { count: 1, score: score || 0 };
    }
    totalScore += score || 0;
  });
  return { info, totalScore };
});
// endTime - startTime
function timeDiff(a?: Date | string, b?: Date | string) {
  const t = dayjs(b).toDate().getTime() - dayjs(a).toDate().getTime();
  let n: string | number = (t / 60 / 60 / 1000).toFixed(1);
  if (Number(n) === Math.floor(Number(n))) {
    n = Math.floor(Number(n));
  }
  return n + "小时";
}
async function initHome() {
  await fetchMatchDetail();
  await getuserquestion();
  updateCountdown();
  timer.value = window.setInterval(updateCountdown, 1000);
}

onMounted(async () => {
  await initHome();
});
onUnmounted(() => {
  if (timer.value) clearInterval(timer.value);
});

async function fetchMatchDetail() {
  try {
    const data = await asyncgetactivity({ ID: activityId.value });
    matchDetail.value = data || {};
  } catch {
    ElMessage.error("获取比赛信息失败");
  }
  // 获取比赛题目，便于计算总分
  if (matchDetail.value?.ID) {
    try {
      const { asyncselectmatchquestion } = await import("../../api");
      const res = await asyncselectmatchquestion({
        activityid: matchDetail.value.ID,
      });
      matchQuestion.value = res?.[0]?.matchquestion || [];
    } catch (error) {
      console.error("获取比赛题目失败", error);
    }
  } else {
    matchQuestion.value = [];
  }
  if (!user.value) {
    console.error("请先登录,获取报名用户信息");
    return;
  }
  // 获取报名用户
  try {
    const activityuser = await asyncgetactivityuser({
      activityid: activityId.value,
    });
    Object.assign(matchDetail.value, {
      activityuser: [activityuser],
    });
  } catch (e) {
    Object.assign(matchDetail.value, {
      activityuser: [],
    });
  }
}

function updateCountdown() {
  const now = Date.now();
  let end = matchDetail.value?.activityendtime
    ? new Date(matchDetail.value.activityendtime)
    : new Date();
  let start = matchDetail.value?.activitystarttime
    ? new Date(matchDetail.value.activitystarttime)
    : new Date();
  if (start.getTime() > now) {
    n.value = "开始";
    Object.assign(time, dhms(start, now));
  } else {
    n.value = "结束";
    Object.assign(time, dhms(end, now));
  }
}

const matchuser = ref<any>(null);
// 判断当前用户是否已答题（通过接口判断）
const hasAnswered = computed(() => {
  const u = user.value;
  if (!u || !matchDetail.value) return false;
  // 拉取当前用户答题信息
  if (
    !matchuser.value ||
    matchuser.value?.activity?.ID !== matchDetail.value.ID
  ) {
    return false;
  }
  // OI模式下，判断userquestion中是否有当前用户
  // if (matchDetail.value.format === 'OI' && matchuser.value?.userquestion) {
  return !!matchuser.value.userquestion.find((v: any) => v.userid == u.ID);
  // }
  // 其它模式可根据实际业务判断
  return false;
});
async function getuserquestion() {
  try {
    if (!user.value) {
      return console.error("请先登录,获取比赛用户信息");
    }
    matchuser.value = await asyncselectmatchuserquestion({
      ID: matchDetail.value.ID,
      my: true,
    });
  } catch (error) {
    console.error("获取比赛用户信息失败", error);
  }
}

// 激活码弹窗及报名流程
const invitationDialog = ref(false);
const invitationvalue = ref<string>();
const invitationPassed = ref(false); // 标记当前用户本场比赛邀请码是否已通过

const isSignedUp = computed(() => {
  return !!matchDetail.value.activityuser?.find(
    (e: any) => e.userid === user.value?.ID
  );
});

// 报名
async function signUpAndEnter() {
  const success = await signUp();
  if (success) {
    goToMatchCore();
  }
}
// 报名具体逻辑
async function signUp(): Promise<boolean> {
  try {
    await asyncchangeactivityuser({
      activityid: matchDetail.value.ID,
    });
    await fetchMatchDetail();
    const n = matchDetail.value.activityuser?.find(
      (e: any) => e.userid === user.value?.ID
    );
    if (n) {
      ElMessage.success("报名成功");
      return true;
    } else {
      ElMessage.error("报名失败");
      return false;
    }
  } catch (e: any) {
    ElMessage.error(String(e));
    return false;
  }
}
// 封装：校验本地缓存邀请码
function checkInvitationLocal(): boolean {
  const localKey = `${user.value?.ID}-${matchDetail.value?.ID}`;
  const localCode = localStorage.getItem(localKey);
  return matchDetail.value?.invitation?.split(",").includes(localCode);
}
// 邀请码弹窗确认
const invitationSubmit = async () => {
  if (!invitationvalue.value) {
    ElMessage.error("请输入邀请码");
    return;
  }
  const valid = matchDetail.value?.invitation
    ?.split(",")
    .includes(invitationvalue.value);
  if (valid) {
    localStorage.setItem(
      `${user.value?.ID}-${matchDetail.value?.ID}`,
      invitationvalue.value
    );
    invitationDialog.value = false;
    invitationvalue.value = "";
    invitationPassed.value = true;
    await signUpAndEnter();
  } else {
    ElMessage.error("邀请码输入错误");
  }
};

// 主流程：点击“开始答题/查看答题”
async function goToMatch(event?: MouseEvent) {
  if (event && typeof event.preventDefault === "function")
    event.preventDefault();
  if (!user.value) {
    ElMessage.error("请先登录");
    goToLogin();
    return;
  }
  // 已报名用户直接进入
  if (isSignedUp.value) {
    goToMatchCore();
    return;
  }
  // 未报名且有邀请码
  if (matchDetail.value?.invitation) {
    if (invitationPassed.value || checkInvitationLocal()) {
      invitationPassed.value = true;
      await signUpAndEnter();
    } else {
      invitationDialog.value = true;
    }
    return;
  }
  // 未报名且无邀请码
  await signUpAndEnter();
}

// 进入比赛页面
function goToMatchCore() {
  router.push({
    name: "比赛答题",
    params: { ID: matchDetail.value.ID, index: 0 },
  });
}

function goToLogin() {
  router.push({
    name: "登录",
    query: {
      redirect: router.currentRoute.value.fullPath, // 记录当前页面路径
    },
  });
}
</script>

<style scoped>
.match-tab-container {
  background: #f5f6fa;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.home-h5-header {
  padding: 24px 20px 10px 20px;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.home-h5-status-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 20px 10px 20px;
  background: #fff;
}

.home-h5-title {
  font-size: 18px;
  font-weight: bold;
  color: #222;
}

.no-match-info-tips {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.home-h5-card {
  background: #fff;
  border-radius: 12px;
  margin: 16px 16px 0 16px;
  padding: 18px 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}

.home-h5-row {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  font-size: 14px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
}

.home-h5-question-count {
  font-weight: normal;
  margin-left: 10px;
}

.contact-info-row {
  flex-direction: column;
  align-items: flex-start;
  border-top: 1px solid #eee;
  padding-top: 15px;
  margin-top: 15px;
}

.contact-info-row .contact-qr-code {
  margin-left: 0;
  margin-top: 8px;
  width: 100%;
  text-align: center;
}

.invitation-form .contact-info-row.in-dialog-contact {
  flex-direction: column;
  align-items: center;

  border-top: none;
  padding-top: 0;
  margin-top: 0;
  width: 100%;

  border-bottom: 1px solid #eee;
  padding-bottom: 16px;
  margin-bottom: 0;
}

.invitation-form .contact-info-row.in-dialog-contact > span:first-child {
  font-size: 13px;
  color: #555;
  text-align: center;
  margin-bottom: 8px;
}

.invitation-form .contact-info-row.in-dialog-contact .contact-qr-code {
  margin-left: 0;
  margin-top: 0;
  width: auto;
  text-align: center;
}

.invitation-form .contact-info-row.in-dialog-contact .contact-qr-code img {
  display: block;
}

.home-h5-desc {
  margin-top: 16px;
  min-height: 100px;
  flex-direction: column;
}

.home-h5-desc-title {
  font-weight: bold;
  margin-bottom: 8px;
}

.home-h5-desc-content {
  color: #666;
  font-size: 14px;
  min-height: 60px;
  word-break: break-all;
  font-weight: normal;
}

.match-status-container {
  margin: 18px auto 0;
  /* Adjusted margin */
  width: 100%;
  /* Adjusted width */
  text-align: center;
  padding-bottom: 15px;
  /* Add padding to separate from contact info if needed */
}

.match-end-btn {
  width: 90%;
  margin: 28px 5% 0 5%;
  height: 48px;
  font-size: 14px;
  border-radius: 24px;
  color: #909399;
  border: none;
  background-color: rgb(243.9, 244.2, 244.8);
  color: var(--el-color-info-light-5) !important;
  background-color: var(--el-color-info-light-9) !important;
  border-color: var(--el-color-info-light-8) !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.home-h5-btn {
  width: 90%;
  margin: 0 5%;
  /* Adjusted margin, removed top margin as it's handled by container */
  height: 48px;
  font-size: 14px;
  border-radius: 24px;
  color: #fff;
  border: none;
  background: #409eff;
  box-shadow: 0 2px 8px rgba(25, 190, 107, 0.08);
}

.home-h5-btn.blue,
.el-button.blue {
  background: #409eff !important;
  border-color: #409eff !important;
  color: #fff !important;
}

.invitation-form {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 0 8px 0;
  gap: 20px;
}

.invitation-form .el-input {
  width: 100%;
}

.invitation-form .el-button {
  width: 100%;
  max-width: 320px;
  margin-top: 8px;
  font-size: 16px;
  border-radius: 20px;
  background: #409eff;
  border-color: #409eff;
  color: #fff;
}

.el-dialog__header {
  text-align: center;
  font-size: 18px;
  font-weight: bold;
  color: #222;
}

.el-dialog__body {
  padding-top: 0;
}
</style>
